﻿//
// © Algobox Ltd - Benn Eichhorn
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.Interop.SterlingTrader;
using Algobox.Feeds.Finance.Simulators;
using Algobox.Feeds.Finance.Bats.Adaptors;
using Algobox.Objects.Finance.Assets.Stock;
using System.Collections.Concurrent;
using Algobox.Structure.Finance.Strategies.SpikeArb;
using Algobox.Structure.Finance.Strategies.Terrapin;
using Algobox.Structure.Finance.Strategies.Moss;
using Algobox.Structure.Finance.Strategies.Dastan;

namespace Zephyr
{
    public class ZephyrLoader
    {
        #region Constructors

        public ZephyrLoader(string username)
        {
            Log.Info(".......");
            Log.Info(":::::::");
            Log.Info("Loading {0}, {1} ", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
            Log.Info("Kites rise highest against the wind - not with it. Winston Churchill");
            Log.Info("User(" + username + ") logged in");

            Username = username;
        }

        #endregion
//////////////////
        #region Member Variables

        /// <summary>
        /// Logger used by this class
        /// </summary>        
        private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();

        private Algobox.Apps.Finance.Zephyr.ZephyrApp _application;

        #endregion
//////////////////
        #region Properties

        public string Username { get; set; }
        public Algobox.Feeds.Finance.MarketData.IMarketFeedAdaptor MarketFeed { get; set; }
        public Algobox.Feeds.Finance.Trading.ITradingFeedAdaptor TradingFeed { get; set; }

        public System.Windows.Data.ListCollectionView GridPriceMatrix { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewPriceMatrix.View; } }

        public System.Windows.Data.ListCollectionView GridSpikeArbSettings { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewSpikeArbSettings.View; } }
        public System.Windows.Data.ListCollectionView GridSpikeArbExecutions { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewSpikeArbExecutions; } }

        public System.Windows.Data.ListCollectionView GridTerrapinSettings { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewTerrapinStocks.View; } }
        public System.Windows.Data.ListCollectionView GridTerrapinUnits { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewTerrapinUnits; } }
        public System.Windows.Data.ListCollectionView GridTerrapinUnitSummary { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewTerrapinUnitSummary.View; } }

        public System.Windows.Data.ListCollectionView GridMossSettings { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewMossStocks.View; } }
        public System.Windows.Data.ListCollectionView GridMossUnits { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewMossUnits; } }
        public System.Windows.Data.ListCollectionView GridMossUnitSummary { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewMossUnitSummary.View; } }

        public System.Windows.Data.ListCollectionView GridDastanSettings { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewDastanStocks.View; } }
        public System.Windows.Data.ListCollectionView GridDastanUnits { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewDastanUnits; } }
        public System.Windows.Data.ListCollectionView GridDastanUnitSummary { get { return Algobox.Apps.Finance.Zephyr.ZephyrApp.ViewDastanUnitSummary.View; } }


        public bool IsConnected { get; set; }

        /// <summary>
        /// True when SterlingWrapper has connected to Stering Trader
        /// </summary>
        public bool IsSterlingTraderToggleOn { get; private set; }

        public bool IsBatsReplayToggleOn { get; private set; }

        /// <summary>
        /// True when SterlingWrapper has connected to Simulation trading interface
        /// </summary>
        public bool IsSterlingSimulationToggleOn { get; private set; }

        #endregion
//////////////////
        #region Functions
        
        internal bool Connect_BatsReplay()
        {
            lock (this)
            {
                if (!IsBatsReplayToggleOn)
                {
                    Log.Info("Connecting Bats Replay");
                    PitchFileMarketFeedAdaptor marketFeed = new PitchFileMarketFeedAdaptor();
                    TradingSimulator tradingFeed = new TradingSimulator();

                    if (!marketFeed.Start())
                        return false;

                    if (!tradingFeed.Start())
                        return false;

                    MarketFeed = marketFeed;
                    TradingFeed = tradingFeed;

                    ConcurrentDictionary<string, StockSecurity> stocks = new ConcurrentDictionary<string, StockSecurity>();

                    Algobox.Data.Finance.BatsReplayTestData dataSource = new Algobox.Data.Finance.BatsReplayTestData(stocks);

                    _application = new Algobox.Apps.Finance.Zephyr.ZephyrApp(stocks, marketFeed, tradingFeed, dataSource, dataSource, dataSource, dataSource);
                    IsBatsReplayToggleOn = true;
                }
            }
            return true;
        }

        /// <summary>
        /// Loads the SterlingWrapper and return true when connected
        /// </summary>
        /// <returns></returns>
        public bool Connect_Sterling()
        {
            lock (this)
            {
                if (!IsSterlingTraderToggleOn)
                {
                    Log.Info("Connecting Sterling");
                    try
                    {                        
                        // Sterling Trader price feed
                        Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor marketFeed = new Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor("SterlingTrader");
                        // Sterling Trader price feed
                        Algobox.Apps.Finance.SterlingTrader.OrderAdaptor tradingFeed = new Algobox.Apps.Finance.SterlingTrader.OrderAdaptor("SterlingTrader");
                        
                        SterlingWrapper.QuoteManager = (QuoteManagement)marketFeed;
                        SterlingWrapper.OrderManager = (OrderManagement)tradingFeed;

                        if (!marketFeed.Start())
                            return false;

                        if (!tradingFeed.Start())
                            return false;

                        MarketFeed = marketFeed;
                        TradingFeed = tradingFeed;

                        ConcurrentDictionary<string, StockSecurity> stocks = new ConcurrentDictionary<string, StockSecurity>();

                        // Spike data
                        //Algobox.Structure.Finance.Strategies.SpikeArb.ISpikeArbData spikeData = new Algobox.Data.Finance.SterlingSpikeTestData(stocks);
                        Algobox.Structure.Finance.Strategies.SpikeArb.ISpikeArbData spikeData = new Algobox.Data.Finance.LiquidView.LiquidViewDataInterface(stocks);

                        // Terrapin data
                        //Algobox.Data.Finance.BatsReplayTestData dataContract = new Algobox.Data.Finance.BatsReplayTestData(stocks);
                        Algobox.Data.Finance.SterlingTestData dataContract = new Algobox.Data.Finance.SterlingTestData(stocks);

                        _application = new Algobox.Apps.Finance.Zephyr.ZephyrApp(stocks, marketFeed, tradingFeed, spikeData, dataContract, dataContract, dataContract);

                        IsSterlingTraderToggleOn = true;
                        return true;
                    }
                    catch
                    {
                        IsSterlingTraderToggleOn = false;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Loads the SterlingWrapper and return true when connected
        /// </summary>
        /// <returns></returns>
        public bool Connect_SterlingSimulation()
        {
            lock (this)
            {
                if (!IsSterlingSimulationToggleOn)
                {
                    Log.Info("Connecting Sterling");
                    try
                    {
                        // Sterling Trader price feed
                        Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor marketFeed = new Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor("SterlingTrader");
                        SterlingWrapper.QuoteManager = (QuoteManagement)marketFeed;

                        TradingSimulator tradingFeed = new TradingSimulator();
                        
                        if (!marketFeed.Start())
                            return false;

                        if (!tradingFeed.Start())
                            return false;

                        MarketFeed = marketFeed;
                        TradingFeed = tradingFeed;

                        ConcurrentDictionary<string, StockSecurity> stocks = new ConcurrentDictionary<string, StockSecurity>();

                        // Spike data
                        Algobox.Structure.Finance.Strategies.SpikeArb.ISpikeArbData spikeData = new Algobox.Data.Finance.SterlingSpikeTestData(stocks);
                        //Algobox.Structure.Finance.Strategies.SpikeArb.ISpikeArbData spikeData = new Algobox.Data.Finance.LiquidView.LiquidViewDataInterface(stocks);

                        // Terrapin data
                        Algobox.Data.Finance.BatsReplayTestData dataContract = new Algobox.Data.Finance.BatsReplayTestData(stocks);
                        //Algobox.Data.Finance.SterlingTestData dataContract = new Algobox.Data.Finance.SterlingTestData(stocks);

                        _application = new Algobox.Apps.Finance.Zephyr.ZephyrApp(stocks, marketFeed, tradingFeed, spikeData, dataContract, dataContract, dataContract);

                        IsSterlingSimulationToggleOn = true;
                        return true;
                    }
                    catch
                    {
                        IsSterlingSimulationToggleOn = false;
                    }
                }
            }
            return false;
        }


        internal void SpikeArb_SaveSettings()
        {
            _application.SpikeArbSave();
        }

        internal bool SpikeArb_LoadSettings()
        {
            return _application.SpikeArbLoad();
        }

        internal void SpikeArb_UnloadSettings()
        {
            _application.SpikeArbUnload();
        }

        internal void SpikeArb_Pause(SpikeArbManagement.Pause type)
        {
            _application.SpikeArbManager.PauseStrategy(type);
        }

        internal void SpikeArb_ChangeAccount(string account)
        {
            SpikeArbManagement.Account = account;
        }

        internal void Terrapin_SaveSettings()
        {
            _application.TerrapinSave();
        }

        internal bool Terrapin_LoadSettings()
        {
            return _application.TerrapinLoad();
        }

        internal void Terrapin_UnloadSettings()
        {
            _application.TerrapinUnload();
        }

        internal void Terrapin_Add(StockSecurity stockSecurity, string account, int value, int entry, int exit, int period)
        {
            _application.TerrapinManager.AddOrUpdate(Guid.NewGuid(),
                stockSecurity,
                account,
                value,
                entry, exit, period, period).IsEnabled = true;
        }

        internal void Terrapin_Add(IEnumerable<StockSecurity> securities, string account, int value, int entry, int exit, int period)
        {
            foreach (StockSecurity stockSecurity in securities)
            {
                _application.TerrapinManager.AddOrUpdate(Guid.NewGuid(),
                    stockSecurity,
                    account,
                    value,
                    entry, exit, period, period).IsEnabled = true;
            }
        }

        internal void Terrapin_Remove(TerrapinStock strategy)
        {
            _application.TerrapinManager.Remove(strategy);
        }




        internal void Dastan_SaveSettings()
        {
            _application.DastanSave();
        }

        internal bool Dastan_LoadSettings()
        {
            return _application.DastanLoad();
        }

        internal void Dastan_UnloadSettings()
        {
            _application.DastanUnload();
        }

        internal void Dastan_Add(StockSecurity stockSecurity, string account, int value, int entry, int exit, int period, int ticks)
        {
            _application.DastanManager.AddOrUpdate(Guid.NewGuid(),
                stockSecurity,
                account,
                value,
                entry, exit, period, ticks).IsEnabled = true;
        }

        internal void Dastan_Add(IEnumerable<StockSecurity> securities, string account, int value, int entry, int exit, int period, int ticks)
        {
            foreach (StockSecurity stockSecurity in securities)
            {
                _application.DastanManager.AddOrUpdate(Guid.NewGuid(),
                    stockSecurity,
                    account,
                    value,
                    entry, exit, period, ticks).IsEnabled = true;
            }
        }


        internal void Dastan_Remove(DastanStock strategy)
        {
            _application.DastanManager.Remove(strategy);
        }



        internal void Moss_SaveSettings()
        {
            _application.MossSave(Username);
        }

        internal bool Moss_LoadSettings()
        {
            return _application.MossLoad(Username);
        }

        internal void Moss_UnloadSettings()
        {
            _application.MossUnload();
        }

        internal void Moss_Add(StockSecurity stockSecurity, string account)
        {
            _application.MossManager.AddOrUpdate(Guid.NewGuid(),
                stockSecurity,
                account,
                10000, 70, 30, 5, 14, 2);
        }

        internal void Moss_Remove(MossStock strategy)
        {
            _application.MossManager.Remove(strategy);
        }


        internal void Exit()
        {            
            Log.Info("Exiting Sterling");
            try
            {
                if (_application != null)
                {
                    _application.SpikeArbManager.StopStrategy();
                    _application.StopStrategy();
                }

                if (MarketFeed != null)
                    MarketFeed.Stop();

                if (TradingFeed != null)
                    TradingFeed.Stop();

            }
            catch
            { }
            

            
            Log.Info("{0} Terminated", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
            Log.Info(":::::::");
            Log.Info(".......");
        }

        internal void BatsReplay_LoadFile(string filename)
        {
            if (IsBatsReplayToggleOn && _application != null)
            {
                System.IO.FileInfo fi = new System.IO.FileInfo(filename);
                ((Algobox.Feeds.Finance.Bats.Adaptors.PitchFileMarketFeedAdaptor)_application.MarketFeed).ProcessFile(fi);
            }
        }


        #endregion
//////////////////
        #region Enums



        #endregion

    }
}
